package com.vendar.oauth;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.SortedSet;

import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.HTTP;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.http.HttpResponse;

/*
 * Helper class for processing the open-auth verify.
 * flow:
 * 	1. get an instance with consumer's key & secret pair.
 * 	2. init the app engine's verify urls.
 * 	3. get app engine's credit.
 * 	4. get user's credit.
 * 	5. ask app engine to verify the two credits.
 */
public class OAuthHelper {
	protected String mAppKey = null;
	protected String mAppSecret = null;
	protected CommonsHttpOAuthConsumer mHttpOAuth = null;
	protected OAuthProvider mOAuthProvider = null;
	protected boolean mReady = false;
	
	/*
	 * we need a consumer key&secred pair from the app engine.
	 */
	public OAuthHelper(String appKey,String appSecret){
		this.mAppKey = appKey;
		this.mAppSecret = appSecret;
	}
	
	public String GetAppKey(){
		return mAppKey;
	}
	
	public String GetAppSecret(){
		return mAppSecret;
	}
	
	public boolean GetReady(){
		return mReady;
	}
	
	public boolean GoAuth(Activity activity,String callback){
		if( mReady ){
			mReady = RequestAppEngineCredit(activity, callback);
		}
		return mReady;
	}
	
	/*
	 * setup app engine's verify system's urls.
	 */
	protected boolean SetupAppEngine( String reqTokenUrl, String accessTokenUrl, String authUrl){
		mHttpOAuth = new CommonsHttpOAuthConsumer(mAppKey, mAppSecret);
		mOAuthProvider = new DefaultOAuthProvider(reqTokenUrl, accessTokenUrl, authUrl);
		return true;
	}
	
	/*
	 * request the credit from app engine.
	 */
	protected boolean RequestAppEngineCredit(Activity activity,String callback){
		boolean credit = false;
		try {
			String authurl = mOAuthProvider.retrieveRequestToken(mHttpOAuth, callback);
			activity.startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(authurl)));
			credit = true;
		} catch (Exception e) {
			Log.e("OAuthHelper","request app engine credit failed!");
		}
		return credit;
	}
	
	/*
	 * get authed user info wrapper.
	 */
	public OAuthAccount GetOAuthedUserInfo(Intent intent){
		OAuthAccount user = null;
		Uri uri = intent.getData();
		String verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
		try{
			mOAuthProvider.setOAuth10a(true);
			mOAuthProvider.retrieveAccessToken(mHttpOAuth, verifier);
		}catch(Exception e){
			Log.e("OAuthHelper","retrieve access token failed!");
			return null;
		}
		SortedSet<String> useridstr = mOAuthProvider.getResponseParameters().get("user_id");
		user = new OAuthAccount(null,useridstr.first(),
				mHttpOAuth.getToken(),mHttpOAuth.getTokenSecret());
		return user;
	}
	
	public HttpResponse SignRequest(String token,String secret,String url,List params){
		HttpPost post = new HttpPost(url);
		try{
			post.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
		}catch(UnsupportedEncodingException e){
			e.printStackTrace();
		}
		post.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
		return SignRequest(token, secret, post);
	}
	public HttpResponse SignRequest(String token,String tokenSecret,HttpPost post){
		mHttpOAuth = new CommonsHttpOAuthConsumer(mAppKey,mAppSecret);
		mHttpOAuth.setTokenWithSecret(token,tokenSecret);
		HttpResponse response = null;
		try {
			mHttpOAuth.sign(post);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			response = (HttpResponse) new DefaultHttpClient().execute(post);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
		}
}
